home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / ip / ka9q / src890906.arc / PCGEN.ASM < prev    next >
Assembly Source File  |  1989-03-25  |  9KB  |  456 lines

  1.     .MODEL    MEMMOD,C
  2.     LOCALS
  3.     %MACS
  4.     .LALL
  5.     extrn    ctick:proc
  6.  
  7. ; Hardware vector for timer linkage
  8. ; We use the timer hardware channel here instead of the indirect BIOS
  9. ; channel (1ch) because the latter is sluggish when running under DoubleDos
  10. TIMEVEC    EQU    08h
  11.  
  12.     .DATA
  13.     public    Intstk,Stktop,Spsave,Sssave
  14.     extrn    Isat:byte
  15. Spsave    dw    ?        ; Save location for SP during interrupts
  16. Sssave    dw    ?        ; Save location for SS during interrupts
  17. Intstk    dw    512 dup(?)    ; Interrupt working stack
  18. Stktop    equ    $        ; SP set here when entering interrupt
  19. mtasker    db    ?        ; Type of higher multitasker, if any
  20.  
  21.     .CODE
  22. dbase    dw    @Data
  23. jtable    dw    l0,l1,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12,l13,l14,l15    
  24.  
  25. ; common routine for interrupt return
  26.     public    doret
  27.     label    doret    far
  28.     cmp    Isat,1
  29.     jnz    @@1        ; Only one 8259, so skip this stuff
  30.     mov    al,0bh        ; read in-service register from
  31.     out    0a0h,al        ; secondary 8259
  32.     nop            ; settling delay
  33.     nop
  34.     nop
  35.     in    al,0a0h        ; get it
  36.     or    al,al        ; Any bits set?
  37.     jz    @@1        ; nope, not a secondary interrupt
  38.     mov    al,20h        ; Get EOI instruction
  39.     out    0a0h,al        ; Secondary 8259 (PC/AT only)
  40. @@1:    mov    al,20h        ; 8259 end-of-interrupt command
  41.     out    20h,al        ; Primary 8259
  42.     pop    es
  43.     pop    di
  44.     pop    si
  45.     pop    bp
  46.     pop    dx
  47.     pop    cx
  48.     pop    bx
  49.     pop    ax
  50.     mov    ss,Sssave
  51.     mov    sp,Spsave    ; restore original stack context
  52.     pop    ds
  53.     iret
  54.  
  55. ; Null interrupt handler
  56.     public    nullvec
  57. nullvec    proc
  58.     iret
  59. nullvec    endp
  60.  
  61. ; istate - return current interrupt state
  62.     public    istate
  63. istate    proc
  64.     pushf
  65.     pop    ax
  66.     and    ax,200h
  67.     jnz    @@1
  68.     ret
  69. @@1:    mov    ax,1
  70.     ret
  71. istate    endp
  72.  
  73. ; dirps - disable interrupts and return previous state: 0 = disabled,
  74. ;           1 = enabled
  75.     public dirps
  76. dirps    proc
  77.     pushf            ; save state on stack
  78.     cli            ; interrupts off
  79.     pop    ax        ; original flags -> ax
  80.     and    ax,200h        ; 1<<9 is IF bit
  81.     jnz    @@1        ; nonzero -> interrupts were on
  82.     ret
  83. @@1:    mov    ax,1
  84.     ret
  85. dirps    endp
  86.  
  87. ; restore - restore interrupt state: 0 = off, nonzero = on
  88.     public    restore
  89. restore    proc
  90.     arg is:word
  91.     test    is,0ffffh
  92.     jz    @@1
  93.     sti
  94.     ret
  95. @@1:    cli
  96.     ret
  97. restore    endp
  98.  
  99. ; multitasker types
  100. NONE        equ    0
  101. DOUBLEDOS    equ    1
  102. DESQVIEW    equ    2
  103.  
  104. ; Relinquish processor so other task can run
  105.     public    giveup
  106. giveup    proc
  107.     pushf        ;save caller's interrupt state
  108.     sti        ;re-enable interrupts
  109.     cmp    mtasker, DOUBLEDOS
  110.     jnz    @@1
  111.     mov    al,2        ; 110 ms
  112.     mov    ah,0eeh
  113.     int    21h
  114.     popf        ; restore interrupts
  115.     ret
  116.  
  117. @@1:    cmp    mtasker, DESQVIEW
  118.     jnz    @@2
  119.     mov    ax, 1000h
  120.     int    15h
  121.     popf        ; restore interrupts
  122.     ret
  123.  
  124. @@2:    hlt        ; wait for an interrupt
  125.     popf        ; restore interrupts
  126.     ret
  127. giveup    endp
  128.  
  129. ; check for a multitasker running
  130.     public    chktasker
  131. chktasker    proc
  132.     mov    mtasker,NONE
  133.     ; do the doubledos test
  134.     mov    ah,0e4h
  135.     int    21h
  136.     cmp    al,1
  137.     jz    @@1
  138.     cmp    al,2
  139.     jnz    @@2
  140. @@1:    mov    mtasker, DOUBLEDOS
  141.     ret
  142.  
  143.     ; test for desqview
  144. @@2:    mov    ax, 2b01h
  145.     mov    cx, 4445h
  146.     mov    dx, 5351h
  147.     int    21h
  148.     cmp    al, 0ffh
  149.     jnz    @@3
  150.     ret
  151.  
  152. @@3:    mov    mtasker, DESQVIEW
  153.     ret
  154. chktasker    endp
  155.  
  156. ; getss - Read SS for debugging purposes
  157.     public    getss
  158. getss    proc
  159.     mov    ax,ss
  160.     ret
  161. getss    endp
  162.  
  163. ; Internet checksum subroutine
  164. ; Compute 1's-complement sum of data buffer
  165. ; Uses an unwound loop inspired by "Duff's Device" for performance
  166. ;
  167. ; Called from C as
  168. ; unsigned short
  169. ; lcsum(buf,cnt)
  170. ; unsigned short *buf;
  171. ; unsigned short cnt;
  172.     public    lcsum
  173. lcsum    proc
  174.     arg    buf:ptr,cnt:word
  175.  
  176.     if    @Datasize NE 0
  177.         uses    ds,si
  178.         lds    si,buf    ; ds:si = buf
  179.     else
  180.         uses    si
  181.         mov    si,buf    ; ds:si = buf (ds already set)
  182.     endif
  183.  
  184.     mov    cx,cnt        ; cx = cnt
  185.     cld            ; autoincrement si
  186.     mov    ax,cx
  187.     shr    cx,1        ; cx /= 16, number of loop iterations
  188.     shr    cx,1
  189.     shr    cx,1
  190.     shr    cx,1
  191.  
  192.     inc    cx        ; make fencepost adjustment for 1st pass
  193.     and    ax,15        ; ax = number of words modulo 16
  194.     shl    ax,1        ; *=2 for word table index
  195.     lea    bx,jtable    ; bx -> branch table
  196.     add    bx,ax        ; index into jump table
  197.     clc            ; initialize carry = 0
  198.     mov    dx,0        ; clear accumulated sum
  199.     jmp    word ptr cs:[bx]    ; jump into loop
  200.  
  201. ; Here the real work gets done. The numeric labels on the lodsw instructions
  202. ; are the targets for the indirect jump we just made.
  203. ;
  204. ; Each label corresponds to a possible remainder of (count / 16), while
  205. ; the number of times around the loop is determined by the quotient.
  206. ;
  207. ; The loop iteration count in cx has been incremented by one to adjust for
  208. ; the first pass.
  209. deloop:    lodsw
  210.     adc    dx,ax
  211. l15:    lodsw
  212.     adc    dx,ax
  213. l14:    lodsw
  214.     adc    dx,ax
  215. l13:    lodsw
  216.     adc    dx,ax
  217. l12:    lodsw
  218.     adc    dx,ax
  219. l11:    lodsw
  220.     adc    dx,ax
  221. l10:    lodsw
  222.     adc    dx,ax
  223. l9:    lodsw
  224.     adc    dx,ax
  225. l8:    lodsw
  226.     adc    dx,ax
  227. l7:    lodsw
  228.     adc    dx,ax
  229. l6:    lodsw
  230.     adc    dx,ax
  231. l5:    lodsw
  232.     adc    dx,ax
  233. l4:    lodsw
  234.     adc    dx,ax
  235. l3:    lodsw
  236.     adc    dx,ax
  237. l2:    lodsw
  238.     adc    dx,ax
  239. l1:    lodsw
  240.     adc    dx,ax
  241. l0:    loop    deloop        ; :-)
  242.  
  243.     adc    dx,0        ; get last carries
  244.     adc    dx,0
  245.     mov    ax,dx        ; result into ax
  246.     xchg    al,ah        ; byte swap result (8088 is little-endian)
  247.     ret
  248. lcsum    endp
  249.  
  250. ; Link timer handler into timer chain
  251. ; Arg == address of timer handler routine
  252. ; MUST be called exactly once before uchtimer is called!
  253.  
  254. toff    dw    ?        ; save location for old vector
  255. tseg    dw    ?        ;  must be in code segment
  256.  
  257.     public    chtimer
  258. chtimer    proc
  259.     arg    vec:far ptr
  260.     uses    ds
  261.  
  262.     mov    ah,35h        ; get current vector
  263.     mov    al,TIMEVEC
  264.     int    21h        ; puts vector in es:bx
  265.     mov    cs:tseg,es    ; stash
  266.     mov    cs:toff,bx
  267.  
  268.     mov    ah,25h
  269.     mov    al,TIMEVEC
  270.     lds    dx,vec        ; ds:si = vec
  271.  
  272.     int    21h        ; set new vector
  273.     ret
  274. chtimer    endp
  275.  
  276. ; unchain timer handler from timer chain
  277. ; MUST NOT be called before chtimer!
  278.     public    uchtimer
  279. uchtimer    proc
  280.     uses    ds
  281.  
  282.     mov    ah,25h
  283.     mov    al,TIMEVEC
  284.     mov    dx,toff
  285.     mov    ds,tseg
  286.     int    21h        ; restore old vector
  287.     ret
  288. uchtimer    endp
  289.  
  290. ; Clock tick interrupt handler. Note the use of "label" rather than "proc"
  291. ; here, necessitated by the fact that "proc" automatically generates BP-saving
  292. ; code that we don't want here.
  293.  
  294.     public    btick
  295.     label    btick    far
  296.  
  297.     pushf
  298.     push    ds
  299.     cli
  300.     mov    ds,cs:dbase    ; establish interrupt data segment
  301.  
  302.     mov    Sssave,ss    ; stash user stack context
  303.     mov    Spsave,sp
  304.  
  305.     mov    ss,cs:dbase
  306.     lea    sp,Stktop
  307.  
  308.     push    ax        ; save user regs on interrupt stack
  309.     push    bx
  310.     push    cx
  311.     push    dx
  312.     push    bp
  313.     push    si
  314.     push    di
  315.     push    es
  316.  
  317.     call    ctick
  318.  
  319.      pop    es
  320.     pop    di
  321.     pop    si
  322.     pop    bp
  323.     pop    dx
  324.     pop    cx
  325.     pop    bx
  326.     pop    ax
  327.     mov    ss,Sssave
  328.     mov    sp,Spsave    ; restore original stack context
  329.     pop    ds
  330.     popf
  331.     jmp    dword ptr [toff]        ; link to previous vector
  332.  
  333. ; Convert 32-bit int in network order to host order (dh, dl, ah, al)
  334. ; Called from C as
  335. ; int32 get32(char *cp);
  336.  
  337.     public    get32
  338. get32    proc
  339.     arg    cp:ptr
  340.     if    @Datasize NE 0
  341.         uses    ds,si
  342.         lds    si,cp    ; ds:si = cp
  343.     else
  344.         uses    si
  345.         mov    si,cp    ; ds:si = cp (ds already set)
  346.     endif
  347.  
  348.     cld
  349.     lodsw
  350.     mov    dh,al    ; high word to dx, a-swapping as we go
  351.     mov    dl,ah
  352.     lodsw
  353.     xchg    al,ah    ; low word stays in ax, just swap
  354.     ret
  355. get32    endp
  356.  
  357. ; Convert 16-bit int in network order to host order (ah, al)
  358. ; Called from C as
  359. ; int16 get16(char *cp);
  360.  
  361.     public    get16
  362. get16    proc
  363.     arg    cp:ptr
  364.     if    @Datasize NE 0
  365.         uses    ds,si
  366.         lds    si,cp    ; ds:si = cp
  367.     else
  368.         uses    si
  369.         mov    si,cp    ; ds:si = cp (ds already set)
  370.     endif
  371.  
  372.     cld
  373.     lodsw
  374.     xchg    al,ah    ; low word stays in ax, just swap
  375.     ret
  376. get16    endp
  377.  
  378. ; Convert 32-bit int to network order, returning new pointer
  379. ; Called from C as
  380. ; char *put32(char *cp,int32 x);
  381.  
  382.     public    put32
  383. put32    proc
  384.     arg    cp:ptr,x:dword
  385.     if    @Datasize NE 0
  386.         uses    ds,di,si
  387.         les    di,cp    ; es:di = cp
  388.         mov    ax,ss    ; our parameter is on the stack, and ds might not
  389.         mov    ds,ax    ;   be pointing to ss.
  390.     else
  391.         uses    di,si
  392.         mov    di,cp    ; es:di = cp
  393.         mov    ax,ds    ; point es at data segment
  394.         mov    es,ax
  395.     endif
  396.  
  397.     cld
  398.     lea    si,x    ; point si to input doubleword
  399.     lodsw        ; fetch low word of machine version
  400.     mov    dh,al    ; swap bytes and save
  401.     mov    dl,ah
  402.     lodsw        ; fetch high word
  403.     xchg    ah,al    ; byte swap
  404.     stosw        ; store in output
  405.     mov    ax,dx    ; retrieve low word and store in output
  406.     stosw
  407.     mov    ax,di    ; return incremented output pointer
  408.     if    @Datasize NE 0
  409.         mov    dx,es    ; upper half of pointer
  410.     endif
  411.     ret
  412. put32    endp
  413.  
  414. ; Convert 16-bit int to network order, returning new pointer
  415. ; Called from C as
  416. ; char *put16(char *cp,int16 x);
  417.  
  418.     public    put16
  419. put16    proc
  420.     arg    cp:ptr,x:word
  421.     uses    di,si
  422.     if    @Datasize NE 0
  423.         les    di,cp    ;es:di = cp
  424.     else
  425.         mov    di,cp    ; es:di = cp
  426.         mov    ax,ds
  427.         mov    es,ax
  428.     endif
  429.     cld
  430.     mov    ax,x    ; fetch source word in machine order
  431.     xchg    ah,al    ; swap bytes
  432.     stosw        ; save in network order
  433.     mov    ax,di    ; return new output pointer to user
  434.     if    @Datasize NE 0
  435.         mov    dx,es    ; upper half of pointer
  436.     endif
  437.     ret
  438. put16    endp
  439.  
  440. ; kbraw - raw, nonblocking read from console
  441. ; If character is ready, return it; if not, return -1
  442.     public    kbraw
  443. kbraw    proc
  444.     mov    ah,06h    ; Direct Console I/O
  445.     mov    dl,0ffh    ; Read from keyboard
  446.     int    21h    ; Call DOS
  447.     jz    @@1    ; zero flag set -> no character ready
  448.     mov    ah,0    ; valid char is 0-255
  449.     ret
  450. @@1:    mov    ax,-1    ; no char, return -1
  451.     ret
  452. kbraw    endp
  453.  
  454.     end
  455.